package com.bndg.blackjack.ui

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.os.Trace
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import com.bndg.blackjack.AppUtils
import com.bndg.blackjack.BlackjackGame
import com.bndg.blackjack.BlackjackListener
import com.bndg.blackjack.Card
import com.bndg.blackjack.GameAction
import com.bndg.blackjack.GameResult
import com.bndg.blackjack.GameState
import com.bndg.blackjack.GameViewModel
import com.bndg.blackjack.InteractiveMsgListener
import com.bndg.blackjack.MsgManager
import com.bndg.blackjack.R
import com.bndg.blackjack.Turn
import com.bndg.blackjack.services.ClientService
import com.bndg.blackjack.services.IDataCallback
import com.bndg.blackjack.services.ServerService
import com.bndg.blackjack.widget.ChipView
import java.util.LinkedList


/**
 * @author r
 * @date 2024/10/11
 * @description Blackjack主界面
 */
class BlackjackActivity : AppCompatActivity(), View.OnClickListener, IDataCallback {
    // 是否为联机模式
    private var isOnline: Boolean = false
    private val tempAnimateViews: LinkedList<View> = LinkedList()
    private val ANIMATE_DURATION: Long = 250L

    // 是否动画中
    private var isAnimation: Boolean = false
    private val gameViewModel: GameViewModel by viewModels()

    private lateinit var ll_panel: ViewGroup
    private lateinit var rl_chips: View
    private lateinit var rl_player_poker: ViewGroup
    private lateinit var rl_dealer_poker: ViewGroup
    private lateinit var dealerControlLayout: View
    private lateinit var playerActionLayout: View
    private lateinit var btnInvite: View
    private lateinit var btnStart: View
    private lateinit var btnPlayerHit: View
    private lateinit var btnPlayerStand: View
    private lateinit var dpvCards: View
    private lateinit var animateCardView: View
    private lateinit var tv_other_score: TextView
    private lateinit var tv_mine_score: TextView
    private lateinit var cv_small: ChipView
    private lateinit var cv_middle: ChipView
    private lateinit var tvMineChips: TextView
    private lateinit var tvOtherChips: TextView
    private lateinit var tvIpPort: TextView

    var isPlayer: Boolean = false

    companion object {
        @JvmStatic
        fun start(
            context: Context,
            isOnline: Boolean = false,
            isPlayer: Boolean = false,
            ipAddress: String = "192.168.1.24",
            port: Int = 8080
        ) {
            val intent = Intent(context, BlackjackActivity::class.java)
            intent.putExtra("isOnline", isOnline)
            intent.putExtra("isPlayer", isPlayer)
            intent.putExtra("ipAddress", ipAddress)
            intent.putExtra("port", port)
            context.startActivity(intent)
        }
    }

    private var clientService: ClientService? = null
    private var clientBound = false
    private val clientServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
            val service = p1 as ClientService.ClientBinder
            clientService = service.getService()
            clientService?.dataCallback = this@BlackjackActivity
            clientBound = true
            AppUtils.log("onServiceConnected: ")
        }

        override fun onServiceDisconnected(p0: ComponentName?) {
            clientBound = false
        }

    }

    private var serverService: ServerService? = null
    private var serverBound = false
    private val serverServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
            val service = p1 as ServerService.ServerBinder
            serverService = service.getService()
            serverService?.dataCallback = this@BlackjackActivity
            serverBound = true
            AppUtils.log("onServiceConnected: ")
            serverService?.startListen()
        }

        override fun onServiceDisconnected(p0: ComponentName?) {
            serverBound = false
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_interactive)
        initView()
        initData()
        initListener()
    }


    fun initView() {
        ll_panel = findViewById(R.id.ll_panel)
        rl_chips = findViewById(R.id.rl_chips)
        dealerControlLayout = findViewById(R.id.ll_dealer_control)
        playerActionLayout = findViewById(R.id.ll_player_action)
        btnInvite = findViewById(R.id.btn_invite)
        btnStart = findViewById(R.id.btn_start)
        btnPlayerHit = findViewById(R.id.bt_player_hit)
        btnPlayerStand = findViewById(R.id.bt_player_stand)
        dpvCards = findViewById(R.id.dpv_cards)
        animateCardView = findViewById(R.id.dpv_animate)
        tv_other_score = findViewById(R.id.tv_other_score)
        tv_mine_score = findViewById(R.id.tv_mine_score)
        cv_small = findViewById(R.id.cv_small)
        cv_middle = findViewById(R.id.cv_middle)
        tvOtherChips = findViewById(R.id.tv_other_chips)
        tvMineChips = findViewById(R.id.tv_mine_chips)
        tvIpPort = findViewById(R.id.tv_ip_port)
        setOnClickListener(
            R.id.btn_invite,
            R.id.btn_start,
            R.id.bt_player_hit,
            R.id.bt_player_stand,
            R.id.cv_small,
            R.id.cv_middle,
        )
    }

    private fun setOnClickListener(vararg ids: Int) {
        for (id in ids) {
            findViewById<View>(id).setOnClickListener(this)
        }
    }

    fun initData() {
        isOnline = intent.getBooleanExtra("isOnline", false)
        isPlayer = intent.getBooleanExtra("isPlayer", false)
        val ipAddress = intent.getStringExtra("ipAddress")
        val port = intent.getIntExtra("port", 8080)
        gameViewModel.showDealerControl.observe(this) { isEnabled ->
            dealerControlLayout.visibility = if (isEnabled) View.VISIBLE else View.GONE
        }

        gameViewModel.showPlayerControl.observe(this) { isEnabled ->
            playerActionLayout.visibility = if (isEnabled) View.VISIBLE else View.GONE
        }

        gameViewModel.enableStartButton.observe(this) { isEnabled ->
            btnStart.isEnabled = isEnabled
        }

        gameViewModel.enableInviteButton.observe(this) { isEnabled ->
            btnInvite.isEnabled = isEnabled
        }

        gameViewModel.enablePlayerButton.observe(this) { isEnabled ->
            btnPlayerHit.isEnabled = isEnabled
            btnPlayerStand.isEnabled = isEnabled
        }

        gameViewModel.enableChipLayout.observe(this) { isEnabled ->
            cv_small.visibility = if (isEnabled) View.VISIBLE else View.INVISIBLE
            cv_middle.visibility = if (isEnabled) View.VISIBLE else View.INVISIBLE
        }
        if (isOnline) {
            if (isPlayer) {
                AppUtils.log("initData: isPlayer")
                ipAddress?.let {
                    ClientService.bind(
                        this,
                        ipAddress,
                        port,
                        clientServiceConnection,
                        Context.BIND_AUTO_CREATE
                    )
                }
                MsgManager.myId = AppUtils.generateId()
                rl_player_poker = findViewById(R.id.rl_dealer_poker)
                rl_dealer_poker = findViewById(R.id.rl_player_poker)
            } else {
                AppUtils.log("initData: isDealer")
                ServerService.bind(this, serverServiceConnection, Context.BIND_AUTO_CREATE)
                if (BlackjackGame.gameState == null) {
                    // initialState是null 证明是发起者 那么初始化一个状态
                    val initialState = GameState().apply {
                        // 庄家id
                        MsgManager.myId = AppUtils.generateId()
                        dealerId = MsgManager.myId
                    }
                    BlackjackGame.gameState = initialState
                    rl_player_poker = findViewById(R.id.rl_player_poker)
                    rl_dealer_poker = findViewById(R.id.rl_dealer_poker)
                }
                gameViewModel.updateGameState(BlackjackGame.gameState!!)
            }
        } else {
            isPlayer = true
            val initialState = GameState().apply {
                // 庄家id
                MsgManager.myId = AppUtils.generateId()
                playerId = MsgManager.myId
                dealerId = AppUtils.generateId()
                isOnline = false
                isInviteMsg = false
                isPlayerAccepted = true
                dealerChips = 1000
                playerChips = 1000
            }
            BlackjackGame.gameState = initialState
            rl_player_poker = findViewById(R.id.rl_dealer_poker)
            rl_dealer_poker = findViewById(R.id.rl_player_poker)
            gameViewModel.updateGameState(initialState)
        }

        // 如果是玩家 调换一下显示
        findViewById<TextView>(R.id.tv_other_name).text = if (isPlayer) "庄家：" else "玩家："
        /*postDelayed({
            // 对方已接受邀请
            BlackjackGame.interactiveState?.let {
                it.isInviteMsg = true
                it.dealerId = PreferencesUtil.getInstance().userId
                // 先只是单聊
                it.playerId = conversationId
                it.isPlayerAccepted = true
                gameViewModel.updateGameState(it)
            }
        },2000)*/
    }

    fun initListener() {
        MsgManager.msgListener = object : InteractiveMsgListener {
            override fun receivedGameState(gameState: GameState) {
                post {
                    BlackjackGame.gameState = gameState
                    gameViewModel.updateGameState(gameState)
                    AppUtils.log("receivedGameState: ${AppUtils.serializeToJson(gameState)}")
                    if (gameState.gameResult == null || gameState.gameResult == GameResult.NORMAL) {
                        // 根据游戏动作判断显示
                        gameState.gameAction?.let {
                            when (it) {
                                GameAction.BET -> {
                                    // 庄家接收到玩家下注操作
                                    if (isPlayer && gameState.isOnline) {
                                    } else {
                                        tv_mine_score.text = ""
                                        tv_other_score.text = ""
                                        BlackjackGame.startGame()
                                    }
                                }

                                GameAction.PLAYER_HIT -> {
                                    // 玩家要牌
                                    if (isPlayer && gameState.isOnline) {
                                        // 得到发送过来的要的牌
                                        showDealerFaceDownCard()
                                        gameState.playerCards?.let {
                                            playerDrawCard(it[it.size - 1])
                                        }
                                    } else {
                                        BlackjackGame.playerHit()
                                    }
                                }

                                GameAction.PLAYER_STAND -> {
                                    // 玩家停牌
                                    if (isPlayer && gameState.isOnline) {
                                        // 停牌
                                        showDealerFaceDownCard()
                                    } else {
                                        BlackjackGame.playerStand()
                                    }
                                }

                                GameAction.DEALER_HIT -> {
                                    // 庄家要牌
                                    if (isPlayer) {
                                        gameState.dealerCards?.let {
                                            val card = it[it.size - 1]
                                            dealerDrawCard(card)
                                        }
                                    } else {

                                    }
                                }

                                GameAction.INITIAL_DEAL -> {
                                    tv_mine_score.text = ""
                                    tv_other_score.text = ""
                                    rl_player_poker.removeAllViews()
                                    rl_dealer_poker.removeAllViews()
                                    // 显示总筹码
                                    showChips()
                                    gameState.playerCards?.let {
                                        for (card in it) {
                                            playerDrawCard(card)
                                        }
                                    }
                                    gameState.dealerCards?.let {
                                        for (card in it) {
                                            dealerDrawCard(card)
                                        }
                                    }
                                }

                                GameAction.FINAL -> {}
                            }
                        }
                    } else {
                        showDealerFaceDownCard()
                        ll_panel.removeViewAt(ll_panel.childCount - 1)
                        toast(BlackjackGame.getResultString(gameState.gameResult!!))
                        if (gameState.playerChips < 50) {
                            toast("你没有足够的筹码了")
                        }
                        showChips()
                    }
                }
            }

            override fun receivedPlayerAcceptedMsg() {
                // 对方已接受邀请
                post {
                    BlackjackGame.gameState?.let {
                        it.isPlayerAccepted = true
                        gameViewModel.updateGameState(it)
                    }
                }
            }

            override fun sentMsg(gameStateJson: String) {
                if (isPlayer) {
                    clientService?.sentMsg(gameStateJson)
                } else {
                    serverService?.sentMsg(gameStateJson)
                }
            }

            override fun receivedRejectMsg() {
                toast("对方拒绝了邀请")
            }

            override fun receivedPlayerLeftMsg() {
                toast("玩家离开了")
                post {
                    val initialState = GameState().apply {
                        dealerId = MsgManager.myId
                    }
                    BlackjackGame.gameState = initialState
                    gameViewModel.updateGameState(initialState)
                }
            }

            override fun receivedDealerLeftMsg() {
                toast("庄家离开了")
            }
        }

        BlackjackGame.listener = object : BlackjackListener {
            override fun showHand(playerHand: MutableList<Card>, dealerHand: MutableList<Card>) {
                BlackjackGame.gameState?.let {
                    gameViewModel.updateGameState(it)
                    rl_player_poker.removeAllViews()
                    rl_dealer_poker.removeAllViews()
                    // 显示庄家手牌
                    for (card in dealerHand) {
                        dealerDrawCard(card)
                    }
                    // 显示玩家手牌
                    for (card in playerHand) {
                        playerDrawCard(card)
                    }
                    if (isPlayer) {
                    } else {
                        // 发送initialled
                        showChips()
                        sendMessage(it)
                    }
                }

            }

            /**
             * 玩家抽牌结束
             */
            override fun playerHitEnd(card: Card) {
                playerDrawCard(card)
                // 通知玩家抽取的牌
                BlackjackGame.gameState?.let {
                    it.gameAction = GameAction.PLAYER_HIT
                    if (it.isOnline) {
                        sendMessage(it)
                    }
                    gameViewModel.updateGameState(it)
                }

            }

            override fun playerStandEnd(switchToDealer: Boolean) {
                BlackjackGame.gameState?.let {
                    gameViewModel.updateGameState(it)
                    if (switchToDealer) {
                        // 需要切换到庄家回合
                        if (it.isOnline) {
                            sendMessage(it)
                        }                    }
                    BlackjackGame.dealerAction()
                }

            }

            override fun dealerHitEnd(card: Card) {
                post {
                    dealerDrawCard(card)
                    BlackjackGame.gameState?.let {
                        it.gameAction = GameAction.DEALER_HIT
                        sendMessage(it)
                        gameViewModel.updateGameState(it)
                        BlackjackGame.dealerAction()
                    }
                }
            }

            override fun gameOver(result: GameResult) {
                BlackjackGame.gameState?.let {
                    sendMessage(it)
                }
                toast(BlackjackGame.getResultString(result))
                showChips()
                gameViewModel.updateGameState(BlackjackGame.gameState!!)
            }

            override fun needCheckOver() {
                if (!isAnimation && !isPlayer) {
                    BlackjackGame.checkIsOver()
                }
            }
        }
    }

    private fun post(function: () -> Unit) {
        postDelayed(function, 0)
    }

    fun postDelayed(function: () -> Unit, delay: Long) {
        Handler(Looper.getMainLooper()).postDelayed(function, delay)
    }

    private fun showChips() {
        BlackjackGame.gameState?.let {
            if (isPlayer) {
                tvMineChips.text = it.playerChips.toString()
                tvOtherChips.text = it.dealerChips.toString()
            } else {
                tvMineChips.text = it.dealerChips.toString()
                tvOtherChips.text = it.playerChips.toString()
            }
        }

    }

    private fun sendMessage(it: GameState) {
        if (it.isOnline) {
            val gameStateJson = AppUtils.serializeToJson(it)
            if (isPlayer) {
                clientService?.sentMsg(gameStateJson)
            } else {
                serverService?.sentMsg(gameStateJson)
            }
        } else {
            // 单机判断游戏状态
            MsgManager.msgListener?.receivedGameState(it)
        }
    }

    /**
     * 庄家抽一张牌
     */
    private fun dealerDrawCard(card: Card) {
        val childCount = rl_dealer_poker.childCount
        val pokerCard =
            LayoutInflater.from(this).inflate(R.layout.item_bj_card, null, false) as CardView
        val layoutParams = RelativeLayout.LayoutParams(
            AppUtils.dp2px(50f),
            AppUtils.dp2px(70f)
        )
        layoutParams.marginStart = AppUtils.dp2px(childCount * 24f)
        pokerCard.visibility = View.INVISIBLE
        pokerCard.layoutParams = layoutParams
        pokerCard.cardElevation = AppUtils.dp2px(childCount * 2f + 4f) * 1f
        pokerCard.findViewById<TextView>(R.id.top_left_text).text = card.rank
        pokerCard.findViewById<TextView>(R.id.bottom_right_text).text = card.rank
        pokerCard.findViewById<TextView>(R.id.middle_suit).text =
            BlackjackGame.getSuit(card.suit)
        if (isPlayer) {
            pokerCard.findViewById<View>(R.id.rl_face_up).visibility =
                if (card.isFaceDown) View.INVISIBLE else View.VISIBLE
            pokerCard.findViewById<View>(R.id.dpv_face_down).visibility =
                if (card.isFaceDown) View.VISIBLE else View.INVISIBLE
        }
        pokerCard.tag = card.isFaceDown
        rl_dealer_poker.addView(pokerCard)
        doHitAnimation(pokerCard)
    }

    /**
     * 玩家抽一张牌
     */
    private fun playerDrawCard(card: Card) {
        val childCount = rl_player_poker.childCount
        val pokerCard =
            LayoutInflater.from(this).inflate(R.layout.item_bj_card, null, false) as CardView
        val layoutParams = RelativeLayout.LayoutParams(
            AppUtils.dp2px(50f),
            AppUtils.dp2px(70f)
        )
        layoutParams.marginStart = AppUtils.dp2px(childCount * 24f)
        pokerCard.visibility = View.INVISIBLE
        pokerCard.layoutParams = layoutParams
        pokerCard.cardElevation = AppUtils.dp2px(childCount * 2f + 4f) * 1f
        pokerCard.findViewById<TextView>(R.id.top_left_text).text = card.rank
        pokerCard.findViewById<TextView>(R.id.bottom_right_text).text = card.rank
        pokerCard.findViewById<TextView>(R.id.middle_suit).text =
            BlackjackGame.getSuit(card.suit)
        rl_player_poker.addView(pokerCard)
        doHitAnimation(pokerCard)
    }

    /**
     * 发一张牌
     */
    private fun doHitAnimation(pokerCard: View) {
        AppUtils.log("正在动画中?: $isAnimation");
        if (isAnimation) {
            // 正在动画中
            tempAnimateViews.add(pokerCard)
            return
        }
        isAnimation = true
        post {
            // 获取发牌牌堆的坐标
            val location = IntArray(2)
            animateCardView.getLocationOnScreen(location)
            val startX = location[0]
            val startY = location[1]

            val pokerCardLocation = IntArray(2)
            pokerCard.getLocationOnScreen(pokerCardLocation)
            val targetX = pokerCardLocation[0] * 1.0f
            val targetY = pokerCardLocation[1] * 1.0f
            // 设置卡片起始位置
            animateCardView.translationX = 0f // 起始 x 坐标
            animateCardView.translationY = 0f // 起始 y 坐标

            // 使用动画移动到目标位置
            val animatorX: ObjectAnimator = ObjectAnimator.ofFloat(
                animateCardView, "translationX",
                0f, targetX - startX
            )
            animatorX.interpolator = AccelerateInterpolator()
            val animatorY: ObjectAnimator = ObjectAnimator.ofFloat(
                animateCardView, "translationY",
                0f, targetY - startY
            )
            animatorY.interpolator = AccelerateInterpolator()
            val animatorSet = AnimatorSet()
            animatorSet.playTogether(animatorX, animatorY)
            animatorSet.setDuration(ANIMATE_DURATION) // 动画持续时间
            animatorSet.addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    // tag  isFaceDown true 不需要翻转 否则需要
                    val needFlip = pokerCard.tag == null || pokerCard.tag == false
                    if (needFlip) {
                        // 翻转
                        doFlipAnimator(pokerCard)
                    } else {
                        // 玩家->不显示庄家的暗牌
                        animateCardView.translationX = 0f
                        animateCardView.translationY = 0f
                        animateCardView.rotationY = 0f
                        animateCardView.alpha = 1f
                        pokerCard.visibility = View.VISIBLE
                        isAnimation = false
                        val tempView = tempAnimateViews.pollFirst()
                        if (null != tempView) {
                            doHitAnimation(tempView)
                        } else {
                            // 全部动画执行完毕 需要更新玩家的分数
                            AppUtils.log("玩家显示点数: ")
                            BlackjackGame.gameState?.let {
                                if(it.playerCards.isNullOrEmpty()) {
                                    return
                                }
                                tv_mine_score.text =
                                    "(${BlackjackGame.calculateScore(it.playerCards!!)})"
                            }
                        }
                    }
                }
            })
            animatorSet.start()
        }
    }

    /**
     * 翻转动画
     */
    private fun doFlipAnimator(pokerCard: View) {
        val flipAnimatorSet = AnimatorSet()
        // 3. 翻转动画
        val flipAnimator = ObjectAnimator.ofFloat(animateCardView, "rotationY", 0f, 180f)
        val fadeInAnimator = ObjectAnimator.ofFloat(animateCardView, "alpha", 1f, 0f)
        flipAnimatorSet.duration = 200 // 翻转动画持续时间
        flipAnimatorSet.playTogether(flipAnimator, fadeInAnimator)
        // 4. 翻转完成后重置 animateView
        flipAnimatorSet.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                animateCardView.translationX = 0f
                animateCardView.translationY = 0f
                animateCardView.rotationY = 0f
                animateCardView.alpha = 1f
                pokerCard.visibility = View.VISIBLE
                isAnimation = false
                val tempView = tempAnimateViews.pollFirst()
                if (null != tempView) {
                    doHitAnimation(tempView)
                } else {
                    // 全部动画执行完毕
                    AppUtils.log("全部动画执行完毕 显示点数: ");
                    BlackjackGame.gameState?.let {
                        if (isPlayer && it.isOnline) {
                            val dealerCards = it.dealerCards
                            if (dealerCards != null && dealerCards.size >= 2 && !dealerCards[1].isFaceDown) {
                                tv_other_score.text =
                                    "(${BlackjackGame.calculateScore(it.dealerCards!!)})"
                            }
                            tv_mine_score.text =
                                "(${BlackjackGame.calculateScore(it.playerCards!!)})"
                        } else {
                            // 庄家去判断游戏结果
                            tv_mine_score.text =
                                "(${BlackjackGame.calculateScore(it.playerCards!!)})"
                            tv_other_score.text =
                                "(${BlackjackGame.calculateScore(it.dealerCards!!)})"
                            BlackjackGame.checkIsOver()
                        }
                    }
                }
            }
        })
        flipAnimatorSet.start()
    }

    override fun onClick(view: View) {
        if (AppUtils.isFastDoubleClick()) {
            return
        }
        when (view.id) {
            R.id.btn_invite -> {
                // 发送邀请 如果已经开始return
                if (false) {
                    BlackjackGame.startGame()
                    return
                }
                BlackjackGame.gameState?.let {
                    // 如果没有接受邀请 且已经离开
                    if (!it.isPlayerAccepted || it.isPlayerLeft) {
                        it.isInviteMsg = true
                        it.dealerId = MsgManager.myId
                        // 先只是单聊 初始化筹码
                        it.dealerChips = 1000
                        it.playerChips = 1000
                        it.playerId = MsgManager.playerId
                        sendMessage(it)
                    }
                }
            }

            R.id.btn_start -> {
                tv_mine_score.text = ""
                tv_other_score.text = ""
                BlackjackGame.startGame()
            }

            // 玩家要牌
            R.id.bt_player_hit -> {
                if (isAnimation) return
                BlackjackGame.gameState?.let {
                    it.gameAction = GameAction.PLAYER_HIT
                    sendMessage(it)
                }
            }

            R.id.bt_player_stand -> {
                if (isAnimation) return
                BlackjackGame.gameState?.let {
                    it.gameAction = GameAction.PLAYER_STAND
                    it.currentTurn = Turn.DEALER
                    sendMessage(it)
                    showDealerFaceDownCard()
                    gameViewModel.updateGameState(it)
                }
            }

            R.id.cv_small -> {
                BlackjackGame.gameState?.let {
                    // 下注筹码
                    it.gameResult = null
                    it.isInviteMsg = false
                    it.gameAction = GameAction.BET
                    it.currentChips = 50
                    if (it.playerChips < 50) {
                        toast("筹码不够了")
                        return
                    }
                    it.playerChips -= it.currentChips
                    it.currentTurn = Turn.DEALER
                    gameViewModel.updateGameState(it)
                    doChipThrowAnimation(cv_small, it)
                }
            }

            R.id.cv_middle -> {
                BlackjackGame.gameState?.let {
                    // 下注筹码
                    it.gameResult = null
                    it.isInviteMsg = false
                    it.gameAction = GameAction.BET
                    it.currentChips = 100
                    if (it.playerChips < 100) {
                        toast("筹码不够了")
                        return
                    }
                    it.playerChips -= it.currentChips
                    it.currentTurn = Turn.DEALER
                    gameViewModel.updateGameState(it)
                    doChipThrowAnimation(cv_middle, it)
                }
            }

        }
    }

    private fun toast(string: String) {
        Toast.makeText(this, string, Toast.LENGTH_LONG).show()
    }

    private fun doChipThrowAnimation(chipView: ChipView, gameState: GameState) {
        val newChipView = ChipView(this, null)
        newChipView.layoutParams = chipView.layoutParams
        newChipView.setChipColor(chipView.getChipColor())
        newChipView.setRingColor(chipView.getRingColor())
        newChipView.setChipValue(chipView.getChipValue())
        ll_panel.addView(newChipView)
        // 设置卡片起始位置
        newChipView.translationX = 0f // 起始 x 坐标
        newChipView.translationY = 0f // 起始 y 坐标
        // 获取发牌牌堆的坐标
        val location = IntArray(2)
        chipView.getLocationOnScreen(location)
        val startX = location[0]
        val startY = location[1]

        val pokerCardLocation = IntArray(2)
        rl_chips.getLocationOnScreen(pokerCardLocation)
        val targetX = pokerCardLocation[0] * 1.0f
        val targetY = pokerCardLocation[1] * 1.0f

        // 使用动画移动到目标位置
        val animatorX: ObjectAnimator = ObjectAnimator.ofFloat(
            newChipView, "translationX",
            0f, targetX - startX
        )
        animatorX.interpolator = AccelerateInterpolator()
        val animatorY: ObjectAnimator = ObjectAnimator.ofFloat(
            newChipView, "translationY",
            0f, targetY - startY
        )
        animatorY.interpolator = AccelerateInterpolator()
        val animatorSet = AnimatorSet()
        animatorSet.playTogether(animatorX, animatorY)
        animatorSet.setDuration(ANIMATE_DURATION) // 动画持续时间
        animatorSet.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                showChips()
                sendMessage(gameState)
            }
        })
        animatorSet.start()

    }

    /**
     * 显示庄家的暗牌
     */
    private fun showDealerFaceDownCard() {
        BlackjackGame.gameState?.let {
            val pokerCardView = rl_dealer_poker.getChildAt(1)
            val faceUpView = pokerCardView.findViewById<View>(R.id.rl_face_up)
            val faceDownView = pokerCardView.findViewById<View>(R.id.dpv_face_down)
            if (faceUpView.visibility == View.INVISIBLE) {
                faceUpView.rotationY = 180f
                val flipAnimator = ValueAnimator.ofFloat(0f, 1f)
                flipAnimator.setDuration(200) // 动画持续时间为 1000ms
                flipAnimator.addUpdateListener { animation: ValueAnimator ->
                    val fraction = animation.animatedFraction // 获取动画进度
                    // 设置视图的旋转角度
                    pokerCardView.rotationY = fraction * 180f

                    // 在进度达到 0.5 时切换视图的可见性
                    if (fraction >= 0.5f && faceDownView.visibility == View.VISIBLE) {
                        faceDownView.visibility = View.INVISIBLE
                        faceUpView.visibility = View.VISIBLE
                    }
                }

                flipAnimator.addListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator) {
                        AppUtils.log("动画结束 显示庄家的暗牌")
                        tv_other_score.text =
                            "(${BlackjackGame.calculateScore(it.dealerCards!!)})"
                    }
                })
                flipAnimator.start()
            }

        }

    }

    override fun onBackPressed() {
        // 如果有状态 对方还在 那么发一条消息
        if (BlackjackGame.gameState != null) {
            val needTips =
                if (BlackjackGame.isPlayer()) !BlackjackGame.gameState!!.isDealerLeft else {
                    !BlackjackGame.gameState!!.isPlayerLeft
                }
            if (needTips) {
                AlertDialog.Builder(this)
                    .setMessage("离开黑杰克?")
                    .setPositiveButton("确定") { _, _ ->
                        BlackjackGame.gameState?.let {
                            if (BlackjackGame.isPlayer()) {
                                it.isPlayerLeft = true
                            } else {
                                it.isDealerLeft = true
                            }
                            sendMessage(it)
                        }
                        super@BlackjackActivity.onBackPressed()
                    }
                    .setNegativeButton("取消") { _, _ ->
                    }
                    .show()
                return
            }

        }
        super.onBackPressed()
    }

    override fun onDestroy() {
        super.onDestroy()
        MsgManager.msgListener = null
        BlackjackGame.quit()
        if (serverBound) {
            unbindService(serverServiceConnection)
        }
        if (clientBound) {
            unbindService(clientServiceConnection)
        }
    }

    override fun onReceived(data: String) {
        MsgManager.processMsg(this@BlackjackActivity, data)
    }

    override fun onClientConnected() {
        AppUtils.show("客户端已连接")
    }

    override fun onServerListening(ipAddress: String, serverPort: Int) {
        AppUtils.show("服务器已开启，IP地址为：$ipAddress，端口号为：$serverPort")
        post {
            tvIpPort.text = "IP: $ipAddress:$serverPort"
            tvIpPort.visibility = View.VISIBLE
        }
    }

    override fun onServerConnected(isConnected: Boolean) {
        if (isConnected) {
            AppUtils.show("服务器已连接")
        } else {
            AppUtils.show("服务器已断开")
        }
    }
}